#ifndef EVENTCATCHER_H_
#define EVENTCATCHER_H_

// Irrlicht header
#include "irrlicht.h"

// STL usage headers
#include <iostream>
#include <exception>
#include <vector>

// Boost header for shared_ptr
#include <boost/shared_ptr.hpp>

// EventHandler for the vector in EventCatcher
#include "Handlers/EventHandler.h"

// Allows easier access to irrlicht items of importance
using namespace irr;

/**
 * EventCatcher is a class that enables the user to have a wrapped event
 * receiver that will handle all events through EventHandler objects in
 * its OnEvent() function.
 */
class EventCatcher : public IEventReceiver {
	protected:
		/// Irrlicht context device pointer
		IrrlichtDevice* m_device;
		
		/// Vector of the event handlers
		std::vector<boost::shared_ptr<EventHandler> > m_eventHandlers;
	public:
		
		/**
		 * Constructs EventCatcher and initializes the vector and assigns the m_device pointer.
		 * @param device Device pointer to the IrrlichtDevice in use by the game.
		 */
		EventCatcher(IrrlichtDevice *device);
		
		/**
		 * Handles the OnEvent() request of IEventReceiver-holding functions.
		 * Passes information down to the EventHandler objects in m_eventHandlers.
		 * @param event An SEvent from Irrlicht
		 * @return True if the event was handled, otherwise false.
		 */
		bool OnEvent(const SEvent& event);
		
		/**
		 * Allows the registering of an EventHandler via a shared_ptr, so that
		 * the handler will be called in the chain of responsibility.
		 * @param newhandler A shared_ptr to the EventHandler object to add
		 * @return True if the handler was added, false if the system can't allocate a new vector space
		 */
		bool RegisterEventHandler(boost::shared_ptr<EventHandler>& newhandler) {
			// can we register a new handler?
			try {
				m_eventHandlers.push_back(newhandler);
				return true;
			}
			// if not, let's catch the error so the program will continue.
			catch(std::exception& e) {
				std::cout<<"Standard exception: "<<e.what()<<std::endl;
				return false;
			}
		}
		
		/**
		 * Destroys EventCatcher.
		 */
		virtual ~EventCatcher();
};

#endif /*EVENTCATCHER_H_*/
